package drds.plus.common.model.comparative;

/**
 * 可比较的类 实际上是是两个东西的结合 符号+值 例如 [> 1] , [< 1] , [= 1]
 */
public class Comparative implements Comparable, Cloneable {

    public static final int greater_than = 1;
    public static final int greater_than_or_equal = 2;
    //
    public static final int equal = 3;
    public static final int not_equal = 4;
    //
    public static final int less_than = 5;
    public static final int less_than_or_equal = 6;

    private Comparable value; // 这有可能又是个Comparative，从而实质上表示一课树（比较树）
    private int comparison;

    protected Comparative() {
    }

    public Comparative(int function, Comparable value) {
        this.comparison = function;
        this.value = value;
    }

    /**
     * 表达式取反
     *
     * @param function
     * @return
     */
    public static int reverseComparison(int function) {
        return 7 - function;
    }

    /**
     * 表达式前后位置调换的时候
     *
     * @param function
     * @return
     */
    public static int exchangeComparison(int function) {
        if (function == greater_than) {
            return less_than;
        } else if (function == greater_than_or_equal) {
            return less_than_or_equal;
        } else if (function == less_than) {
            return greater_than;
        }
        if (function == less_than_or_equal) {
            return greater_than_or_equal;
        } else {
            return function;
        }
    }

    public static String getComparisonName(int function) {
        if (function == equal) {
            return "=";
        } else if (function == greater_than) {
            return ">";
        } else if (function == greater_than_or_equal) {
            return ">=";
        } else if (function == less_than_or_equal) {
            return "<=";
        } else if (function == less_than) {
            return "<";
        } else if (function == not_equal) {
            return "<>";
        } else {
            return null;
        }
    }

    /**
     * contains顺序按字符从多到少排列，否则逻辑不对，这里 先这样处理。
     *
     * @param completeStr
     * @return
     */
    public static int getComparisonByCompleteString(String completeStr) {
        if (completeStr != null) {
            String ident = completeStr.toLowerCase();
            if (ident.contains(">=")) {
                return greater_than_or_equal;
            } else if (ident.contains("<=")) {
                return less_than_or_equal;
            } else if (ident.contains("!=")) {
                return not_equal;
            } else if (ident.contains("<>")) {
                return not_equal;
            } else if (ident.contains("=")) {
                return equal;
            } else if (ident.contains(">")) {
                return greater_than;
            } else if (ident.contains("<")) {
                return less_than;
            } else {
                return -1;
            }
        } else {
            return -1;
        }
    }

    public Comparable getValue() {
        return value;
    }

    public void setValue(Comparable value) {
        this.value = value;
    }

    public int getComparison() {
        return comparison;
    }

    public void setComparison(int function) {
        this.comparison = function;
    }

    public int compareTo(Object o) {
        if (o instanceof Comparative) {
            Comparative other = (Comparative) o;
            return this.getValue().compareTo(other.getValue());
        } else if (o instanceof Comparable) {
            return this.getValue().compareTo(o);
        }
        return -1;
    }

    public String toString() {
        if (value != null) {
            StringBuilder sb = new StringBuilder();
            sb.append("(").append(getComparisonName(comparison));
            sb.append(value.toString()).append(")");
            return sb.toString();
        } else {
            return null;
        }
    }

    public Object clone() {
        return new Comparative(this.comparison, this.value);
    }
}
